_Die_AMPEL_ESP_v2.ino

					
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <TextFinder.h>

/***************************** TIME SYNCHRONISATION LIBRARIES *****************************/
#include <NTPClient.h>
#include <WiFiUdp.h>

/***************************** PRIVATE INCLUDES *****************************/
#include "_Die_AMPEL_ESP_v2.h"
#include "Server.h"
#include "HTTP.h"

#define WIFI_CONNECT_TIMEOUT 15
#define GET_STATES_INTERVAL 2000

/***************************** VARIABLES *****************************/
status_flags_t Status;

/**** Headquarters ****/
//const char* ssid = "Waifaaii";  
//const char* password = "luckbastonly_2";

/**** Vodafone router ****/
const char* ssid = "WLAN1-DB246C";  
const char* password = "9C728FC499A"; 

/**** My Hotspot ****/
//const char* ssid = "Ampel";  
//const char* password = "11332244"; 

/**** Edunet network ****/
//const char* ssid = "SWSEDU02";
//const char* password = "IoT.4.SPE";  

char Comand_line[16]; //(max length of line is 10 so far) 
uint8_t i = 0;
uint8_t WiFi_conect_tries = 0;

const char* serverName = "http://ampel101.000webhostapp.com/post.php";
const char* initAddress = "http://ampel101.000webhostapp.com/ip.php";  /**********change to the right file adress*********/ 
const char* Get_states_addr = "http://ampel101.000webhostapp.com/Get.php";

uint16_t Get_states_timer = 0;

// Keep this API Key value to be compatible with the PHP code provided in the project page. 
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key 
String Ampel_state_apiKey = "(t#L~)U|dYjU1Yc~";

ESP8266WebServer server(80);  // Server variable to perform the answer to the POST Request
WiFiClient client;
HTTPClient http;

char global_IP_Server[] = "checkip.dyndns.org";
char externalIP[17];
char externalIP_password[] = "113322";

char AccessPoint_name[] = "Die_Ampel_AccessPoint";
char AccessPoint_password[] = "BohdankoUsmanko";

Wifi_reconnect_t Wifi_timers;  // Structure for correct search for the internet connection (in the case if WiFi is not connected)

 /***************************** FUNKTION PROTOTYPES *****************************/
void UART_routine(status_flags_t* Status, char* Line);
void Reconnect_routine(status_flags_t* Status, Wifi_reconnect_t* Wifi_timers);
void Get_states_routine(status_flags_t* Status, const char* address);

 /************************************* SETUP ************************************/
void setup() 
{
  Serial.begin(9600);
  pinMode(2, OUTPUT); // signal LED
  
  /***************************** WiFi Connection *****************************/
  WiFi.begin(ssid, password);
  
  Serial.println("\nConnecting to WiFi network " + (String)ssid);
  while ((WiFi.status() != WL_CONNECTED) && (WiFi_conect_tries <= WIFI_CONNECT_TIMEOUT)) 
  {
    digitalWrite(2, !(digitalRead(2)));               // LED Blinking during connection
    delay(1000);
    Serial.print("."); 
    WiFi_conect_tries++;
  } 

  if(WiFi_conect_tries >= WIFI_CONNECT_TIMEOUT)
  {
    Serial.println("No WiFi connection\nESP-01 is Creating an Acess Point");
    Serial.println("Network Name: " + (String)AccessPoint_name);
    Serial.println("Network Password: " + (String)AccessPoint_password);
    WiFi.softAP(AccessPoint_name, AccessPoint_password);
    Status.WiFi_Connected = 0;
    digitalWrite(2, HIGH);                              //  NO WiFi! Turn OFF the LED
  }
  else
  {
    Serial.println("\nConnected to WiFi");   
    Serial.print("Local IP: ");
    Serial.println(WiFi.localIP());                   
    digitalWrite(2, LOW);                               // WiFi connected! Turn ON the LED
    Get_Ext_IP(externalIP, global_IP_Server);
    Serial.print("WAN IP: ");
    Serial.println(externalIP);
    POST_Ext_IP(initAddress, externalIP, externalIP_password);
    Status.WiFi_Connected = 1;
    server.on("/SET", HTTP_POST, handlePOST);   /* Call the 'handlePOST' function when a POST request is made to URI "/SET". Reference: https://tttapa.github.io/ESP8266/Chap10%20-%20Simple%20Web%20Server.html LOOK FOR: <form action="/login" method="POST"> */
    server.on("/", handleEMPTY);
    server.begin();                           // Actually start the server
    Serial.println("HTTP server started");
  } 
}

/************************************* LOOP ************************************/
void loop() 
{
  UART_routine(&Status, Comand_line);         // Work with UART Comands received from Arduino
  Reconnect_routine(&Status, &Wifi_timers);   // WiFi reconnection will be implemented in the case of missing connection
  Get_states_routine(&Status, Get_states_addr);
  //server.handleClient();                      // Listen for HTTP requests from clients
  delay(1);
}

void UART_routine(status_flags_t* Status, char* Line)
{
  if(Serial.available() > 0)
  {
      Line[i] = Serial.read();

      if(Line[i] == '\n')
      {
        Line[i-1] = '\0';
        Status->string_received = 1;
        i = 0;
      }
      else
        i++;
  }
  /************* Parcing the Line ************/
  if(Status->string_received == 1)
  {
    //Serial.println(Line);
    if(!strcmp(Line, "alive?")) // Func returns: 0 - the contents of both strings are equal; <0 - the first character that does not match has a lower value in ptr1 than in ptr2; >0 - the first character that does not match has a greater value in ptr1 than in ptr2
    {
      Serial.println("YES");
    }
    else
    {
      if((Line[0] == 'p') && (Line[1] == 'o') && (Line[2] == 's') && (Line[3] == 't') && isDigit(Line[4]) && isDigit(Line[5]) && isDigit(Line[6]) && (isDigit(Line[7])) && isDigit(Line[8])) // We have received a post comand
      {
        send_POST(Line);
      }
      else
      {
        if(!strcmp(Line, "ret_time"))
          Get_time(Status);
        else
        {
          Serial.println("ERR");
        }
      }
    }
    
    memset(Line, 0, sizeof(Line)); // flush the array
    Status->string_received = 0;
  }
}

void Reconnect_routine(status_flags_t* Status, Wifi_reconnect_t* Wifi_timers)
{
  if(Status->WiFi_Connected == 0)              // if WiFi connection is missing
  {
    if(Status->AP_Created == 0)                // if the AP was not created
    {
      Serial.println("No WiFi connection\nESP-01 is Creating an Acess Point");
      Serial.println("Network Name: " + (String)AccessPoint_name);
      Serial.println("Network Password: " + (String)AccessPoint_password);
      WiFi.softAP(AccessPoint_name, AccessPoint_password);
      Status->AP_Created = 1;
    }
    
    Wifi_timers->blink_timer++;
    Wifi_timers->tries_timer++;
    //Serial.println(blink_timer);
/*************************** No WiFi = blinkng with period of BLINK_PERIOD **********************/
    if((Wifi_timers->blink_timer >= 0) && (Wifi_timers->blink_timer <= BLINK_TIME))
    {
      digitalWrite(2, LOW); // aus
    }
    else 
    {
      if((Wifi_timers->blink_timer > BLINK_TIME) &&(Wifi_timers->blink_timer < BLINK_PERIOD))
      {
        digitalWrite(2, HIGH); // ein
      }
      else 
      {
        if(Wifi_timers->blink_timer >= BLINK_PERIOD)
        {
          Wifi_timers->blink_timer = 0;
        }
      }
    }

/*************************** Tries to connect to the Wifi Again **********************/
    if(Wifi_timers->tries_timer >= WIFI_CONNECTION_INTERVAL)
    {
      if(Wifi_timers->delay_timer == 0)      // if we are not waiting for a connection NOW
      {
        Serial.println("WiFi Connection with network " + (String)ssid + " try");  // Start a connection
        WiFi.begin(ssid, password);
      }

      Wifi_timers->delay_timer++;
      if(Wifi_timers->delay_timer >= WIFI_WAIT_DELAY)  // delay is finished
      {
        if(Wifi_timers->check_number < WIFI_CONNECTION_CHECKS)  // if we are not checking WiFi too long
        {
          if(WiFi.status() == WL_CONNECTED)
          {
            Serial.println("\nConnected to WiFi network " + (String)ssid);   
            Serial.print("Local IP: ");
            Serial.println(WiFi.localIP());                   
            digitalWrite(2, LOW);                               // WiFi connected! Turn ON the LED
            Get_Ext_IP(externalIP, global_IP_Server);
            Serial.print("WAN IP: ");
            Serial.println(externalIP);
            POST_Ext_IP(initAddress, externalIP, externalIP_password);
            Status->WiFi_Connected = 1;
            Status->AP_Created = 0;
            
            Wifi_timers->tries_timer = 0;
            Wifi_timers->delay_timer = 0;
            Wifi_timers->check_number = 0;
          }
        }
        else                    // Return to being an AP
        {
            WiFi.softAP(AccessPoint_name, AccessPoint_password);
            Wifi_timers->tries_timer = 0;
            Wifi_timers->delay_timer = 0;
            Wifi_timers->check_number = 0;
        }
        Wifi_timers->check_number++;
      }
    }
  }
}

/*
 * Each GET_STATES_INTERVAL miliseconds - recuest to the Website
 */
void Get_states_routine(status_flags_t* Status, const char* address)
{
  Get_states_timer++;
  if(Get_states_timer >= GET_STATES_INTERVAL)
  {
    Get_Ampel_states(Status, address);
    Get_states_timer = 0;
  }
}